package netbay;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;

import org.apache.axis.utils.StringUtils;

import util.jQgrid.JSONUtil;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

public class WorkerManager {
	public static String TCDRecvCmd = "RecvTCD";
	public static String JPMCRecvCmd = "RecvTCD";
	public static String reTCDTCDCmd = "reTCDTCD";
	public static String reJPMCTCDCmd = "reJPMCTCD";
	public static String testCmd = "Test";
	public static String UpdateDbCmd = "";
	public static String TCDRecvDir = "";
	public static String JPMCRecvDir = "";
	public static String JPMCDesDir = "";
	public static String NetbayTrackUrl = "";
	public static String NetbayTrackUser = "";
	public static String NetbayTrackPassword = "";
	public static String NetbayTrackDocType = "";
	public static String NetbayTrackKeyGet = "";

	// use to prevent from duplicate task
	// it's a queue board to show there is a process on which conversationid
	private static List<String> assignedTCDId;
	private static List<String> assignedJPMCId;
	private static List<String> assignedTestId;
	private static List<String> assignedTCDTCDId;
	private static List<String> assignedJPMCTCDId;
	public static String SFTPrecvPath = "";
	public static String ActionTCDToBank;
	public static String ActionRDToBank;
	public static String ActionBankToRD;
	public static String ActionBankToTCD;
	public static String RDPostUrl;

	public static void assignJob(String cmd) {

		if (cmd.equalsIgnoreCase(TCDRecvCmd)) {

			recvTCD();

		} else if (cmd.equalsIgnoreCase(JPMCRecvCmd)) {

			recvJPMC();

		} else if (cmd.equalsIgnoreCase(testCmd)) {

			System.out.println("get test");

		} else if (cmd.equalsIgnoreCase(UpdateDbCmd)) {
			updateDb();
		}

	}

	private static String doHttpUrlConnectionAction(String desiredUrl)
			throws Exception {
		URL url = null;
		BufferedReader reader = null;
		StringBuilder stringBuilder;

		try {
			// create the HttpURLConnection
			url = new URL(desiredUrl);
			HttpURLConnection connection = (HttpURLConnection) url
					.openConnection();

			// just want to do an HTTP GET here
			connection.setRequestMethod("GET");

			// uncomment this if you want to write output to this url
			// connection.setDoOutput(true);

			// give it 15 seconds to respond
			connection.setReadTimeout(15 * 1000);
			connection.connect();

			// read the output from the server
			reader = new BufferedReader(new InputStreamReader(connection
					.getInputStream()));
			stringBuilder = new StringBuilder();

			String line = null;
			while ((line = reader.readLine()) != null) {
				stringBuilder.append(line + "\n");
			}
			return stringBuilder.toString();
		} catch (Exception e) {
			e.printStackTrace();
			throw e;
		} finally {
			// close the reader; this can throw an exception too, so
			// wrap it in another try/catch block.
			if (reader != null) {
				try {
					reader.close();
				} catch (IOException ioe) {
					ioe.printStackTrace();
				}
			}
		}
	}

	private static void updateDb() {
		// System.out.println("Start check db");
		TransactionManager tm = new TransactionManager();
		List result;
		result = tm.findNotUpdateTransaction();
		String conversationId = null;
		String myUrl = null;
		String resultTrack = "";
		for (int i = 0; i < result.size(); i++) {
			conversationId = (String) result.get(i);
			myUrl = NetbayTrackUrl + "?USERNAME=" + NetbayTrackUser
					+ "&PASSWORD=" + NetbayTrackPassword + "&SRID="
					+ conversationId;
			try {
				resultTrack = doHttpUrlConnectionAction(myUrl);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			resultTrack = resultTrack.trim();
			if (!(resultTrack.equals("null"))) {
				updateTrackToDb(resultTrack, conversationId);
			}
		}
	}

	private static void updateTrackToDb(String strJson, String conversationId) {

		TransactionManager tm = new TransactionManager();
		Gson gson = new Gson();
		JsonParser parser = new JsonParser();

		// String test = "{\"RECEIVED\":[{\"DocumentType\":\"Payment Bank\"," +
		// "\"Reference\":\"DXXX541206459\"," +
		// "\"Comment\":\"jp\"," +
		// "\"Sender\":\"jp001@jp.com\"," +
		// "\"SendTime\":\"2012-01-23 14:56:42\"," +
		// "\"ReceiveTime\":\"2012-01-23 14:56:42\"," +
		// "\"Status\":\"104\"}]}";

		JsonObject obj = (JsonObject) parser.parse(strJson);
		String dataValue = obj.get(WorkerManager.NetbayTrackKeyGet).toString();

		JsonArray trade = null;
		try {
			trade = JSONUtil.convertStringJsonToJSONArray(dataValue);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String docType;
		String conversationID;
		String comment;
		String sender;
		String sendTime;
		String receiveTime;
		String status;
		String receiveTimeDecimal = new String();

		for (int i = 0; i < trade.size(); i++) {
			obj = trade.get(i).getAsJsonObject();
			docType = gson.fromJson(obj.get("DocumentType"), String.class);
			conversationID = gson.fromJson(obj.get("Reference"), String.class);
			comment = gson.fromJson(obj.get("Comment"), String.class);
			sender = gson.fromJson(obj.get("Sender"), String.class);
			sendTime = gson.fromJson(obj.get("SendTime"), String.class);
			receiveTime = gson.fromJson(obj.get("ReceiveTime"), String.class);
			status = gson.fromJson(obj.get("Status"), String.class);

			if (status.equals("104")
					&& docType.equals(WorkerManager.NetbayTrackDocType)) {
				receiveTimeDecimal = dateToDecimal(receiveTime);
				tm.updateTransactionStatusFromGateway(conversationId, "TCD");
				TransactionTraffic traff = new TransactionTraffic();
				TransactionLog log = tm
						.findTransactionByConverId(conversationId);
				traff = tm.findTraffSendTCDByTransactionId(log.getId());
				traff.setProcess(TransactionManager.finSendTcdStatus);
				traff.setEventTime(receiveTimeDecimal);
				traff.setType("TCD");
				tm.insertTrafficStatus(traff);
			}
		}

	}

	private static String dateToDecimal(String date) {
		String[] cut = date.split("[-\\s:]");

		String time = "";

		for (int i = 0; i < cut.length; i++) {
			time += cut[i];
		}
		time += ".000";

		return time;
	}

	private static void recvJPMC() {

		SFTPManager manager = new SFTPManager();
		List<String> fileList = null;
		try {
			fileList = manager.lsForFiles();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (fileList == null || fileList.size() == 0)
			System.out.println("None of files");
		else {
			for (int i = 0; i < fileList.size(); ++i) {
				String fileName = fileList.get(i);

				// need to check before start -- operate only attach file
				// operate on attach file and self-generate ctrl file
				if (fileName.length() > 5) {
					if (fileName.substring(fileName.length() - 4,
							fileName.length()).equalsIgnoreCase(".xml")) {
						String converId = "";
						String[] cut = fileName.split("[--.]");
						if (cut.length > 2) {
							converId = cut[1];
						}
						String attachFileName = fileName;

						if (checkId(converId, JPMCRecvCmd)) {
							Worker myWorker = new Worker(attachFileName,
									JPMCRecvCmd);
							Thread working = new Thread(myWorker);
							working.start();
						}
					}
				}

			}
		}
	}

	private static void recvTCD() {

		FileDao fileMng = new FileDao();

		String TCDStorePath = TCDRecvDir;
		File expFolder = new File(TCDStorePath);
		String[] fileList = null;
		try {
			fileList = fileMng.exploreFolder(expFolder);
			if (fileList.length == 0)
				System.out.println("None of files");
			else {
				for (int i = 0; i < fileList.length; ++i) {
					if (fileList[i].length() > 6) {
						String fileName = fileList[i];

						// need to check before start -- operate only ctrl file
						// operate on attach file and ctrl file
						if (fileName.substring(fileName.length() - 5,
								fileName.length()).equalsIgnoreCase(".ctrl")) {

							String ctrlFileName = fileName;

							// find converID from ctrlFile
							File ctrlFile = new File(WorkerManager.TCDRecvDir
									+ "/" + fileName);
							String converId = TransactionLog
									.getConverId(ctrlFile);

							if (checkId(converId, TCDRecvCmd)) {
								Worker myWorker = new Worker(ctrlFileName,
										TCDRecvCmd);
								Thread working = new Thread(myWorker);
								working.start();
							}
						}
					}

				}
			}
		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	// change to add conversation id of file
	public static boolean checkId(String converId, String cmd) {

		if (cmd.equalsIgnoreCase(TCDRecvCmd)) {
			if (assignedTCDId == null)
				assignedTCDId = new ArrayList<String>();

			if (!assignedTCDId.contains(converId)) {
				assignedTCDId.add(converId);
				return true;
			} else
				return false;
		}
		if (cmd.equalsIgnoreCase(JPMCRecvCmd)) {
			if (assignedJPMCId == null)
				assignedJPMCId = new ArrayList<String>();

			if (!assignedJPMCId.contains(converId)) {
				assignedJPMCId.add(converId);
				return true;
			} else
				return false;

		}
		if (cmd.equalsIgnoreCase(testCmd)) {
			if (assignedTestId == null)
				assignedTestId = new ArrayList<String>();

			if (!assignedTestId.contains(converId)) {
				assignedTestId.add(converId);
				return true;
			} else
				return false;
		}
		if (cmd.equalsIgnoreCase(reTCDTCDCmd)) {
			if (assignedTCDTCDId == null)
				assignedTCDTCDId = new ArrayList<String>();

			if (!assignedTCDTCDId.contains(converId)) {
				assignedTCDTCDId.add(converId);

				return true;
			} else
				return false;
		}
		if (cmd.equalsIgnoreCase(reJPMCTCDCmd)) {
			if (assignedJPMCTCDId == null)
				assignedJPMCTCDId = new ArrayList<String>();

			if (!assignedJPMCTCDId.contains(converId)) {
				assignedJPMCTCDId.add(converId);
				return true;
			} else
				return false;
		}
		return false;
	}

	// nat change to report converId
	public static void reportId(String converId, String cmd) {

		if (cmd.equalsIgnoreCase(TCDRecvCmd)) {
			if (assignedTCDId.contains(converId)) {
				assignedTCDId.remove(converId);
			}
		}
		if (cmd.equalsIgnoreCase(JPMCRecvCmd)) {
			if (assignedJPMCId.contains(converId)) {
				assignedJPMCId.remove(converId);
			}
		}
		if (cmd.equalsIgnoreCase(testCmd)) {
			if (assignedTestId.contains(converId)) {
				assignedTestId.remove(converId);
			}
		}
		if (cmd.equalsIgnoreCase(reTCDTCDCmd)) {
			if (assignedTCDTCDId.contains(converId)) {
				assignedTCDTCDId.remove(converId);
			}
		}
		if (cmd.equalsIgnoreCase(reJPMCTCDCmd)) {
			if (assignedJPMCTCDId.contains(converId)) {
				assignedJPMCTCDId.remove(converId);
			}
		}
	}

}
